#!/usr/bin/env python

"""
Usage: hdvb-to-vdr HDVB_CHANS.SQLITE

Outputs a channels.conf for VDR.
Notes:
PIDs are all 0 so you will have to enable VDR's "Write pids" option.
CA is set to 0xff for all encrypted channels.
All satellite channels are assumed to come from 28.2E.
"""

from __future__ import print_function

import sqlite3
import sys


def load_from_sqlite(filename):
    conn = sqlite3.connect(filename)
    curs = conn.cursor()
    curs.execute("SELECT lcn, service_name, provider_name, tuning_str, " \
            "free_ca_mode, service_id, network_id, services.ts_id " \
            "FROM services, transports " \
            "WHERE services.ts_id = transports.ts_id " \
            "ORDER BY lcn, service_name")
    return curs.fetchall()


def fec_to_vdr(fec):
    if fec == "AUTO":
        return "0"
    else:
        return fec.replace('/', '')


def mod_to_vdr(m):
    if m == "QPSK":
        return "2"
    elif m.startswith("QAM"):
        return m[3:]
    elif m == "8PSK":
        return "5"
    elif m == "16APSK":
        return "6"
    elif m == "8VSB":
        return "10"
    elif m == "16VSB":
        return "11"
    elif m == "DQPSK":
        return "12"
    return "999";


def bw_to_vdr(b):
    b = b[:-3]
    if b == "1.712":
        return "1712"
    else:
        return b


def tm_to_vdr(tm):
    if tm == "AUTO":
        return "0"
    else:
        return tm[:-1]


def gi_to_vdr(g):
    if g == "AUTO":
        return "0"
    elif g.startswith("1/"):
        return g[2:]
    else:
        return g.replace('/', '')


def hier_to_vdr(h):
    if h == "AUTO" or h == "NONE":
        return 0
    else:
        return h


def tuning_to_params_s(t):
    # t is the result of tuning_str.split()
    return "%cC%sM%sO%sS%d" % (t[2], fec_to_vdr(t[4]), mod_to_vdr(t[6]),
            t[5], int(t[0][1]) - 1)


def tuning_to_params_t(t):
    # t is the result of tuning_str.split()
    if t[0] == 'T2':
        t2 = "S1P%s" % t[1]
        t = [t[0],] + t[3:]
    else:
        t2 = ""
    return "I0C%sD%sM%sB%sT%sG%sY%s%s" % \
            (fec_to_vdr(t[3]), fec_to_vdr(t[4]), mod_to_vdr(t[5]),
            bw_to_vdr(t[2]), tm_to_vdr(t[6]), gi_to_vdr(t[7]),
            hier_to_vdr(t[8]), t2)


def sql_row_to_vdr(row):
    t = row[3].split()
    if t[0][0] == 'S':
        f = int(t[1]) / 1000
        params = tuning_to_params_s(t)
        srate = int(t[3]) / 1000
        src = "S28.2E"
    elif t[0][0] == 'T':
        if t[0] == 'T2':
            f = int(t[3])
        else:
            f = int(t[1])
        params = tuning_to_params_t(t)
        srate = 27500;
        src = t[0]
    else:
        print("Sorry, only Freeview and Freesat supported")
    if row[2]:
        name = "%s;%s" % (row[1], row[2])
    else:
        name = "%s" % row[1]
    if int(row[4]):
        ca = "ff"
    else:
        ca = "0"
    return "%s:%d:%s:%s:%d:0:0:0:%s:%d:%d:%d" % \
            (name, f, params, src, srate, ca, row[5], row[6], row[7])


def print_chans(rows):
    lcn = -1000
    for row in rows:
        lcn += 1
        if row[0] != lcn:
            lcn = row[0]
            print(":@%d " % lcn)
        print(sql_row_to_vdr(row))


rows = load_from_sqlite(sys.argv[1])
print_chans(rows)
